package com.party.web.web.controller.subject;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.party.common.constant.Constant;
import com.party.common.paging.Page;
import com.party.common.utils.LangUtils;
import com.party.common.utils.StringUtils;
import com.party.core.model.BaseModel;
import com.party.core.model.article.Article;
import com.party.core.model.article.ArticleGroup;
import com.party.core.model.channel.Channel;
import com.party.core.model.information.Information;
import com.party.core.model.information.InformationType;
import com.party.core.model.subject.Subject;
import com.party.core.model.subject.SubjectApply;
import com.party.core.model.system.RoleEnum;
import com.party.core.model.system.SysConfig;
import com.party.core.model.user.User;
import com.party.core.service.article.IArticleGroupService;
import com.party.core.service.article.IArticleService;
import com.party.core.service.channel.IChannelService;
import com.party.core.service.cos.CosBizService;
import com.party.core.service.information.IInformationService;
import com.party.core.service.information.IInformationTypeService;
import com.party.core.service.subject.ISubjectApplyService;
import com.party.core.service.subject.ISubjectService;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.system.ISysRoleService;
import com.party.core.service.user.IUserService;
import com.party.web.biz.file.FileBizService;
import com.party.core.utils.MyBeanUtils;
import com.party.web.utils.RealmUtils;
import com.party.web.web.annotation.ControlParam;
import com.party.web.web.annotation.DataControl;
import com.party.web.web.dto.AjaxResult;
import com.party.web.web.dto.output.article.ArticleOutput;
import com.party.web.web.dto.output.channel.ChannelOutput;
import com.party.web.web.dto.output.information.InformationOutput;
import com.party.web.web.security.CurrentUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 专题应用
 * 
 * @author Administrator
 *
 */
@Controller
@RequestMapping(value = "/subject/apply")
public class SubjectApplyController {

	@Autowired
	private ISubjectService subjectService;

	@Autowired
	private ISubjectApplyService subjectApplyService;

	@Autowired
	private IUserService userService;

	@Autowired
	private IArticleService articleService;

	@Autowired
	private FileBizService fileBizService;

	@Autowired
	private CosBizService cosBizService;

	@Autowired
	private IArticleGroupService articleGroupService;

    @Autowired
    private IChannelService channelService;

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
	private IInformationService informationService;

    @Autowired
	private IInformationTypeService informationTypeService;

	protected static Logger logger = LoggerFactory.getLogger(SubjectApplyController.class);

	/**
	 * 跳转至列表
	 * 
	 * @return
	 */
	@DataControl
	@RequestMapping(value = "applyList")
	public ModelAndView publishList(@ControlParam(table = "subject", column = "member_id", getMethodName = "getSubjectId")SubjectApply subjectApply, String applyId) {
		ModelAndView mv = new ModelAndView("subject/applyList");

        CurrentUser newCurrentUser = RealmUtils.getNewCurrentUser();
        boolean role = sysRoleService.hasRole(newCurrentUser.getId(), RoleEnum.KNOWING_COMMUNE_ROLE.getCode());

        Subject subject = subjectService.get(subjectApply.getSubjectId());

        mv.addObject("isXzgs",role);
		mv.addObject("isXzgsAdmin",newCurrentUser.isXzgsAdmin());
		mv.addObject("subject", subject);
		mv.addObject("firstId", applyId);
		return mv;
	}

	/**
	 * 栏目列表
	 * @param subjectId
	 * @param applyId
	 * @return
	 */
	@DataControl
	@ResponseBody
	@RequestMapping("getApplyList")
	public AjaxResult getApplyList(@ControlParam(table = "subject", column = "member_id")String subjectId, String applyId) {
		SubjectApply subjectApply = new SubjectApply();
		subjectApply.setSubjectId(subjectId);
		subjectApply.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
		List<SubjectApply> applies = subjectApplyService.list(subjectApply);

		String firstId = applyId;
		if (StringUtils.isEmpty(applyId) && applies.size() > 0) {
			firstId = applies.get(0).getId();
		}

		Map<String, Object> map = Maps.newHashMap();
		map.put("applies", applies);
		map.put("firstId", firstId);
		return AjaxResult.success(map);
	}

    @ResponseBody
    @RequestMapping(value = "loadApplyCategoryJsonData")
    public Map<String, Object> loadApplyCategoryJsonData(String applyId, String title, Page page) {
        Map<String, Object> map = new HashMap<String, Object>();
        SubjectApply subjectApply = subjectApplyService.get(applyId);
        map.put("subjectApply", subjectApply);
        Channel channel = new Channel();
        channel.setMember(applyId);
        channel.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        List<Channel> channels = channelService.listPage(channel,page);

        String filePath = fileBizService.getUploadCIPath(applyId, "channel");
        List<ChannelOutput> channelOutputs = LangUtils.transform(channels, input -> {
            ChannelOutput channelOutput = ChannelOutput.transform(input);
            List<Article> articles = articleService.getByChannelId(input.getId());
            channelOutput.setArticleNum(articles.size());
            channelOutput.setApplyId(applyId);
            String qrCodeUrl = cosBizService.getPreviewPictureUrl(filePath + input.getId());
            channelOutput.setQrCodeUrl(qrCodeUrl);
            return channelOutput;
        });

        map.put("channels", channelOutputs);
        map.put("page", page);
        return map;
    }


	@ResponseBody
	@RequestMapping(value = "loadJsonData")
	public Map<String, Object> loadJsonData(String applyId, String title, String channelId, Page page) {
		Map<String, Object> map = new HashMap<String, Object>();
		SubjectApply subjectApply = subjectApplyService.get(applyId);
		map.put("subjectApply", subjectApply);
		List<Article> articles = new ArrayList<Article>();
		if (subjectApply.getType().equals("article")) {
			Article article = articleService.get(subjectApply.getTargetId());
			if (article != null) {
				articles.add(article);
			}
		} else if (subjectApply.getType().equals("channel")) {
			Article t = new Article();
			t.setTitle(title);
			t.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
			t.setArticleGroupId(subjectApply.getTargetId());
			page.setLimit(10);
            Channel channel = new Channel();
            channel.setId(channelId);
            t.setChannel(channel);
            articles = articleService.webListPage(t, null, page);
		}
		List<ArticleOutput> articleOutputs = LangUtils.transform(articles, input -> {
			String filePath = fileBizService.getUploadCIPath(input.getMemberId(), "article");
			ArticleOutput articleOutput = ArticleOutput.transform(input);
			String fileName = "detail_" + input.getId();
			String qrCodeUrl = cosBizService.getPreviewPictureUrl(filePath + fileName);
			articleOutput.setQrCodeUrl(qrCodeUrl);
			articleOutput.setApplyId(applyId);
			return articleOutput;
		});

		map.put("articles", articleOutputs);
		map.put("page", page);
		return map;
	}

    @RequestMapping(value = "batchAdd/form")
    public ModelAndView batchAddFrom(Page page, String applyId, String channelId, String title) {
        if (StringUtils.isEmpty(applyId) || StringUtils.isEmpty(channelId)) {
            return null;
        }
        ModelAndView mv = new ModelAndView("channel/batchAddArticle");
        SubjectApply subjectApply = subjectApplyService.get(applyId);
        Article t = new Article();
        t.setTitle(title);
        t.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        t.setArticleGroupId(subjectApply.getTargetId());
        page.setLimit(10);
        List<Article> articles = articleService.webListPage(t, null, page);

        for (Article article : articles) {
            if (article.getChannel() != null && StringUtils.isNotEmpty(article.getChannel().getId())) {
                Channel channel = channelService.get(article.getChannel().getId());
                article.setChannel(channel);
            }
        }

        mv.addObject("articles",articles);
        mv.addObject("page",page);
        mv.addObject("applyId",applyId);
        mv.addObject("channelId",channelId);
        mv.addObject("title",title);
        return mv;
    }

    @ResponseBody
    @RequestMapping(value = "batchSave")
    public AjaxResult batchSave(String channelId, String ids) {

        AjaxResult ajaxResult = new AjaxResult();
        try {
            //批量添加文章
            if (StringUtils.isEmpty(channelId)) {
                return AjaxResult.error("分类id不能为空");
            }
            if (StringUtils.isEmpty(ids)) {
                return AjaxResult.error("没有选择文章");
            }
            String[] idsArray = ids.split(",");
            for (String articleId : idsArray) {
                Article article = articleService.get(articleId);
                Channel channel = channelService.get(channelId);
                article.setChannel(channel);
                articleService.update(article);
            }

        } catch (Exception e) {
            logger.error("添加文章异常", e);
            ajaxResult.setSuccess(false);
        }
        ajaxResult.setSuccess(true);
        return ajaxResult;
    }

	/**
	 * 读取列表数据
	 * 
	 * @param page
	 * @param subjectId
	 *            专题id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "publishListJson")
	public Map<String, Object> publishListJson(Page page, String subjectId) {
		page.setLimit(9);
		SubjectApply subjectApply = new SubjectApply();
		subjectApply.setSubjectId(subjectId);
		subjectApply.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
		List<SubjectApply> applies = subjectApplyService.listPage(subjectApply, page);
		for (SubjectApply apply : applies) {
			Subject subject = subjectService.get(apply.getSubjectId());
			apply.setSubjectName(subject.getName());
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("datas", applies);
		map.put("page", page);
		return map;
	}

	/**
	 * 跳转至发布
	 * 
	 * @param id
	 * @return
	 */
	@DataControl
	@RequestMapping(value = "publishApply")
	public ModelAndView publishApply(String id, @ControlParam(table = "subject", column = "member_id") String subjectId) {
		ModelAndView mv = new ModelAndView("subject/publishApply");
		if (StringUtils.isNotEmpty(id)) {
			SubjectApply apply = subjectApplyService.get(id);
			if (null == apply) {
				return new ModelAndView(Constant.ERROR_402);
			}
			mv.addObject("apply", apply);
			if (apply.getType().equals("channel")) {
				ArticleGroup articleGroup = articleGroupService.get(apply.getTargetId());
				mv.addObject("channel", articleGroup);
			}
		}

		Subject subject = subjectService.get(subjectId);
		mv.addObject("subject", subject);

		return mv;
	}

	/**
	 * 跳转至详情
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "applyDetail")
	public ModelAndView subjectDetail(String id, HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("subject/applyDetail");
		SubjectApply apply = subjectApplyService.get(id);
		Subject subject = subjectService.get(apply.getSubjectId());
		if (apply.getType().equals(SubjectApply.TYPE_ARTICLE) || apply.getType().equals(SubjectApply.TYPE_ARTICLE_GROUP)) {
			String url = "http://" + request.getServerName() //服务器地址
					+ ":"
					+ request.getServerPort()           //端口号
					+ apply.getUrl();

			apply.setUrl(url);
		}
		mv.addObject("subject", subject);
		mv.addObject("apply", apply);
		return mv;
	}

	/**
	 * 
	 * @param apply
	 * @param result
	 *            频道名称
	 * @param channelPicture
	 *            频道封面图
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "save")
	public AjaxResult save(SubjectApply apply, BindingResult result, String channelPicture) throws Exception {
		AjaxResult ajaxResult = new AjaxResult();
		// 数据验证
		if (result.hasErrors()) {
			List<ObjectError> allErros = result.getAllErrors();
			ajaxResult.setDescription(allErros.get(0).getDefaultMessage());
			return ajaxResult;
		}
		String memberId = RealmUtils.getCurrentUser().getId();
		if(RealmUtils.getNewCurrentUser().isXzgsAdmin()){
			memberId = RealmUtils.getNewCurrentUser().getPartnerId();
		}

		User user = userService.findByLoginName("admin");
		
		List<SubjectApply> subjectApplies = subjectApplyService.getBySubjectId(apply.getSubjectId());

		if (StringUtils.isNotEmpty(apply.getId())) {
			SubjectApply t = subjectApplyService.get(apply.getId());
			MyBeanUtils.copyBeanNotNull2Bean(apply, t);// 将编辑表单中的非NULL值覆盖数据库记录中的值
			if (t.getType().equals("url")) {
				t.setTargetId(null);
			}

			if (t.getType().equals("channel")) {
				ArticleGroup articleGroup = articleGroupService.get(t.getTargetId());
				if (articleGroup == null) {
					articleGroup = new ArticleGroup();
					articleGroup.setName(apply.getName());
					articleGroup.setPicture(channelPicture);
					articleGroup.setCreateBy(user.getId());
					articleGroup.setUpdateBy(user.getId());
					articleGroup.setMemberId(memberId);
					articleGroup.setIsShow(1);
					String channelId = articleGroupService.insert(articleGroup);
					t.setTargetId(channelId);
					t.setUrl(SubjectApply.MIC_URL + "article/article_group_detail.html?id=" + channelId);
				} else {
					articleGroup.setPicture(channelPicture);
					articleGroup.setName(apply.getName());
					articleGroupService.update(articleGroup);
					t.setUrl(SubjectApply.MIC_URL + "article/article_group_detail.html?id=" + articleGroup.getId());
				}
			}
			
			if (t.getSort() > subjectApplies.size()) {
				return new AjaxResult(false, "当前排序号超出");
			}

			t.setUpdateDate(new Date());
			subjectApplyService.update(t);
		} else {
			apply.setCreateBy(user.getId());
			apply.setUpdateBy(user.getId());
			apply.setMemberId(memberId);

			if (apply.getType().equals("channel")) {
				ArticleGroup articleGroup = new ArticleGroup();
				articleGroup.setName(apply.getName());
				articleGroup.setPicture(channelPicture);
				articleGroup.setCreateBy(user.getId());
				articleGroup.setUpdateBy(user.getId());
				articleGroup.setMemberId(memberId);
				articleGroup.setIsShow(1);
				String channelId = articleGroupService.insert(articleGroup);
				apply.setTargetId(channelId);
				apply.setUrl(SubjectApply.MIC_URL + "article/article_group_detail.html?id=" + channelId);
			}
			
			apply.setSort(subjectApplies.size() + 1);
			
			subjectApplyService.insert(apply);
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("subjectId", apply.getSubjectId());
		map.put("applyId", apply.getId());
		ajaxResult.setData(map);
		ajaxResult.setSuccess(true);
		return ajaxResult;
	}

	/**
	 * 删除栏目
	 */
	@ResponseBody
	@RequestMapping(value = "delete")
	public AjaxResult delete(String applyId, String subjectId) {
		AjaxResult ajaxResult = new AjaxResult();
		try {
			if (StringUtils.isEmpty(applyId)) {
				return new AjaxResult(false);
			}
			if (StringUtils.isNotEmpty(subjectId)) {
				ajaxResult.setData(subjectId);
			}
			boolean flag = true;
			SubjectApply subjectApply = subjectApplyService.get(applyId);
			if (subjectApply.getType().equals("channel")) {
				Article t = new Article();
				t.setArticleGroupId(subjectApply.getTargetId());
				List<Article> articles = articleService.list(t);
				if (articles.size() > 0) {
					flag = false;
				}
			} else if (subjectApply.getType().equals("article") && StringUtils.isNotEmpty(subjectApply.getTargetId())) {
				flag = false;
			}

			if (flag) {
				subjectApplyService.delete(applyId);
				ajaxResult.setSuccess(true);
			} else {
				ajaxResult.setSuccess(false);
				ajaxResult.setDescription("已有文章不能删除");
			}
		} catch (Exception e) {
			logger.error("文章删除异常", e);
		}
		return ajaxResult;
	}

	/**
	 * 更新排序
	 * @param applyId
	 * @param type
	 * @return
	 */
	@ResponseBody
	@RequestMapping("updateSort")
	public AjaxResult updateSort(String applyId, String type) {
		SubjectApply subjectApply = subjectApplyService.get(applyId);
		List<SubjectApply> subjectApplies = subjectApplyService.getBySubjectId(subjectApply.getSubjectId());
		if (subjectApply.getSort() == null) {
			return AjaxResult.error("请先填写序号");
		}
		if (type.equals("up")) {
			if (subjectApply.getSort() != 1) {
				SubjectApply newApply = null;
				Integer sort = subjectApply.getSort() - 1;
				for (SubjectApply s : subjectApplies) {
					if ((s.getSort().equals(sort) || s.getSort() - 1  == sort) && !s.getId().equals(applyId)) {
						newApply = s;
						break;
					}
				}
				if (newApply != null) {
					newApply.setSort(newApply.getSort() + 1);
					subjectApplyService.update(newApply);
				}
				subjectApply.setSort(sort);
				subjectApplyService.update(subjectApply);
			} else {
				return AjaxResult.error("已经是第一位了");
			}
		} else if (type.equals("down")) {
			if (subjectApply.getSort() != subjectApplies.size()) {
				SubjectApply newApply = null;
				Integer sort = subjectApply.getSort() + 1;
				for (SubjectApply s : subjectApplies) {
					if ((s.getSort().equals(sort) || s.getSort() + 1  == sort) && !s.getId().equals(applyId)) {
						newApply = s;
						break;
					}
				}
				if (newApply != null) {
					newApply.setSort(newApply.getSort() - 1);
					subjectApplyService.update(newApply);
				}
				subjectApply.setSort(sort);
				subjectApplyService.update(subjectApply);
			} else {
				return AjaxResult.error("已经是最后一位了");
			}
		}
		return AjaxResult.success();
	}

	/**
	 * 拖曳更新排序
	 * @param jsonStr 排序json字符串
	 * @return
	 */
	@ResponseBody
	@RequestMapping("dragUpdateSort")
	public AjaxResult dragUpdateSort(String jsonStr) {
		if (StringUtils.isEmpty(jsonStr)) {
			return AjaxResult.error("栏目排序json字符串不能为空");
		}
		Map<String, Integer> resultMap = JSONObject.parseObject(jsonStr, Map.class);
		for (Map.Entry<String, Integer> result : resultMap.entrySet()) {
			String id = result.getKey(); // 文章id
			Integer newSort = result.getValue(); // 排序号
			SubjectApply apply = subjectApplyService.get(id);
			apply.setSort(newSort);
			subjectApplyService.update(apply);
		}
		return AjaxResult.success();
	}

    /**
     * 初始化栏目下默认分类，文章所属默认分类
     * @author shenliuhai
     * @date 2020/1/9 11:57
     * @param subjectId
     * @return com.party.web.web.dto.AjaxResult
     */
    @ResponseBody
    @RequestMapping("init/apply/article/category")
    public AjaxResult initApplyArticleCategory(String subjectId) {

        if (StringUtils.isEmpty(subjectId)) {
            return AjaxResult.error("参数为空");
        }

        try {
            List<SubjectApply> applyList = subjectApplyService.getBySubjectId(subjectId);
            User user = userService.findByLoginName("admin");
            for (SubjectApply apply : applyList) {
                Channel channel = new Channel();
                channel.setMember(apply.getId());
                List<Channel> list = channelService.list(channel);
                if (list.size() == 0) {
                    channel.setCreateBy(user.getId());
                    channel.setUpdateBy(user.getId());
                    channel.setIsShow(0);
                    channel.setName("其他");
                    channel.setRemarks("默认分类");
                    channel.setPicture("http://txzapp-10052192.image.myqcloud.com/c94e89415d7d4611b706cecfc43af2ae/image/1571298756456.png");
                    channelService.insert(channel);

                    if (StringUtils.isNotEmpty(apply.getTargetId())) {
                        List<Article> articleList = articleService.getByArticleGroupId(apply.getTargetId());
                        for (Article article : articleList) {
                            article.setChannel(channel);
                            articleService.update(article);
                        }
                    }
                }
            }
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("初始化官网栏目默认分类失败,{}",e);
            e.printStackTrace();
            return AjaxResult.error("初始化官网栏目默认分类失败");
        }
    }


	@ResponseBody
	@RequestMapping("init/information")
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public AjaxResult initInformation(String subjectId) {
		if (StringUtils.isEmpty(subjectId)) {
			return AjaxResult.error("参数为空");
		}
		try {
			List<SubjectApply> applyList = subjectApplyService.getBySubjectId(subjectId);

			InformationType informationType = new InformationType();
			informationType.setName("政策");
			List<InformationType> list = informationTypeService.list(informationType);
			String typeId = "";
			if (list.size() > 0) {
				typeId = list.get(0).getId();
			}
			String memberId = RealmUtils.getNewCurrentUser().getId();

			for (SubjectApply apply : applyList) {

				if (StringUtils.isNotEmpty(apply.getTargetId())) {
					List<Article> articleList = articleService.getByArticleGroupId(apply.getTargetId());
					for (Article article : articleList) {
						Information information = new Information();
						information.setCreateBy(memberId);

						information.setMemberId(memberId);
						information.setInformationTypeId(typeId);
						information.setContent(article.getContent());
						information.setTitle(article.getTitle());
						information.setSubTitle(article.getSubTitle());
						information.setPic(article.getPic());
						information.setReadNum(article.getReadNum());
						information.setCommentNum(1000);
						information.setCityId("");
						information.setSort(1);

						informationService.insert(information);

						try {
							String filePath = fileBizService.getUploadCIPath(information.getCreateBy(), "information");

							String fileName = "consultation_detail_" + information.getId();
							String content = "consultation/consultation_detail.html?id=" + information.getId();
							fileBizService.uploadCloudOut(fileName, filePath, content, information.getCreateBy());
						} catch (Exception e) {
							logger.error("上传服务二维码异常", e);
						}
					}
				}

			}
			return AjaxResult.success();
		} catch (Exception e) {
			logger.error("迁移官网文章到资讯列表失败,{}", e);
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return AjaxResult.error("迁移官网文章到资讯列表失败");
		}
	}

}
